#!/usr/bin/env python3
# Shebang行：指定使用Python3解释器执行此脚本
# 这样可以直接通过 ./文件名 的方式运行脚本

# 导入必要的ROS2模块
import rclpy  # ROS2的Python客户端库，提供核心功能
from rclpy.node import Node  # Node基类，所有ROS2节点都需要继承此类
from example_interfaces.srv import AddTwoInts  # 导入预定义的加法服务接口


class AddTwoIntsServer(Node):
    """
    加法服务器节点类， 继承自Node基类，实现两个整数相加的服务功能
    """

    def __init__(self):
        """
        构造函数：初始化服务器节点
        """
        # 调用父类构造函数，设置节点名称为'add_two_ints_server'， 这个名称将在ROS2网络中唯一标识此节点
        super().__init__('add_two_ints_server')

        # 创建服务对象
        # create_service() 方法用于创建一个ROS2服务
        self.srv = self.create_service(
            AddTwoInts,  # 服务类型：定义了请求和响应的消息格式。 是个类
            # AddTwoInts.Request 包含两个int64字段：a和b
            # AddTwoInts.Response 包含一个int64字段：sum
            'add_two_ints',  # 服务名称：客户端将通过此名称调用服务
            self.add_two_ints_callback  # 回调函数：当收到服务请求时调用的处理函数
        )

        # 记录启动信息到ROS2日志系统，get_logger() 返回节点专用的日志记录器
        self.get_logger().info('Add Two Ints Server 已启动，等待请求...')

    def add_two_ints_callback(self, request, response):
        """
        服务回调函数：处理加法请求，这个函数在每次收到客户端请求时被自动调用
        参数:
            request: AddTwoInts.Request类型，包含客户端发送的数据
                    - request.a: 第一个加数
                    - request.b: 第二个加数
            response: AddTwoInts.Response类型，用于返回计算结果
                     - response.sum: 计算结果

        返回: response: 填充了结果的响应对象
        """
        # 执行加法运算，将结果存储到响应对象中
        response.sum = request.a + request.b

        # 记录请求处理信息，使用f-string格式化字符串，方便调试和监控
        self.get_logger().info(
            f'收到请求: a={request.a}, b={request.b} => 结果: {response.sum}'
        )

        # 返回响应对象给客户端，ROS2框架会自动将此响应发送回调用的客户端
        return response


def main(args=None):
    """
    主函数：程序入口点
    参数:
        args: 命令行参数，通常从sys.argv传入，ROS2会解析这些参数用于节点配置
    """
    # 初始化ROS2系统
    # 这是使用ROS2功能前必须调用的函数，它会设置ROS2的通信基础设施、日志系统等
    rclpy.init(args=args)

    # 创建服务器节点实例，此时会执行__init__方法，创建服务并准备接收请求
    node = AddTwoIntsServer()

    try:
        # 启动节点的事件循环
        # spin()会让程序保持运行，持续处理ROS2事件，包括：服务请求、定时器回调、订阅消息等，这个函数会一直阻塞，直到节点被关闭
        rclpy.spin(node)
    except KeyboardInterrupt:
        # 捕获Ctrl+C中断信号， 优雅地处理用户手动停止程序的情况。 pass表示不做任何特殊处理，直接进入清理阶段
        pass

    # 清理节点资源，释放节点占用的内存、关闭网络连接等，这是良好的编程实践，确保资源正确释放
    node.destroy_node()

    # 关闭ROS2系统，清理ROS2的全局资源，与rclpy.init()对应，程序结束前必须调用此函数！！！
    rclpy.shutdown()


# Python标准的程序入口检查
# 当直接运行此脚本时（而非被import），__name__等于'__main__'
# 这样可以确保只有直接执行脚本时才会调用main函数
if __name__ == '__main__':
    main()